\section{Dynamic Grammar}

A literal string (like ``foo'') indicates a \textit{KEYWORD}
token. Using it in a grammar \textit{registers the keyword} with the
lexer. When it is promoted as a key word, it will no longer be used as
a \textit{LIDENT}, so for example, the \textit{grammar parser}, will
\textit{break some valid programs} before, because \textit{parser} is
now a keyword. This is the convention, to make things simple, you can
find other ways to overcome the problem, but it's too complicated. you
can also say (x= KEYWORD) or pattern match syntax (`LINDENT x) to get
the actual token constructor. The parser may \textit{ignore} trailing
tokens when it succeed.

\textit{LEVELS}  They can be labeled following an entry, like \textit{expr
  LEVEL "mul"}. However, explicitly specifying a level when calling an
entry might \textit{defeat the start/continue mechanism}.

\textit{NEXT} refers to the entry being defined at the following level
regardless of assocaitivity or position.  For \textit{LIST0 elem SEP
  sep} both \textit{LIST0} and \textit{OPT} can match the epsilon, but
its \textit{priority} is lower.  For \textit{TRY}, non-local
backtracking, a \textit{Stream.Error} will be \textit{converted} to a
\textit{Stream.Failure}.


  \begin{ocamlcode}
    expr : [[ TRY f1 -> "f1" | f2 -> "f2" ]]
  \end{ocamlcode}
  
  For \textit{Nested rule} (only one level can be applied)
  
  \begin{ocamlcode}
    [x = expr ; ["+" | "plus" ]; y = expr -> x + y ]
  \end{ocamlcode}
  
  \textit{EXTEND} is an expression (with type unit). It can be
  evaluated anywhere

\subsection{Grammar Modification}

When you extend an entry, by default \textit{the first level} of the
extension extends the first level of the entry.  Listing \ref{Grammar
  modification} lists different usage of \textit{EXTEND, EXTEND LAST,
  EXTEND LEVEL, EXTEND BEFORE}.


\begin{ocamlcode}
open Camlp4.PreCast;
open Format;
value test = Gram.Entry.mk "test";
value p = Gram.Entry.print std_formatter;
EXTEND Gram GLOBAL: test;
  test:
    ["add" LEFTA
	[SELF; "+" ; SELF | SELF; "-" ; SELF]
    | "mult" RIGHTA
	[SELF; "*" ; SELF | SELF; "/" ; SELF]
    | "simple" NONA
	[ "("; SELF; ")"  | INT ] ];
END;
\end{ocamlcode}

\begin{ocamlcode}
#   p test;
test: [ "add" LEFTA
  [ SELF; "+"; SELF
  | SELF; "-"; SELF ]
| "mult" RIGHTA
  [ SELF; "*"; SELF
  | SELF; "/"; SELF ]
| "simple" NONA
  [ "("; SELF; ")"
  | INT ((_)) ] ]
- : unit = ()
\end{ocamlcode}

\begin{ocamlcode}
EXTEND Gram GLOBAL: test;
    test: [[ x = SELF ; "plus1plus" ; y = SELF ]];
END ;
# p test;
test: [ "add" LEFTA
  [ SELF; "plus1plus"; SELF
  | SELF; "+"; SELF
  | SELF; "-"; SELF ]
| "mult" RIGHTA
  [ SELF; "*"; SELF
  | SELF; "/"; SELF ]
| "simple" NONA
  [ "("; SELF; ")"
  | INT ((_)) ] ]
- : unit = ()    
\end{ocamlcode}
\captionof{listing}{Extend Grammar by Default}

\begin{ocamlcode}
EXTEND Gram  test: LAST
    [[x = SELF ; "plus1plus" ; y = SELF ]];
  END;
p test ;

      - : unit = ()
# test: [ "add" LEFTA
  [ SELF; "plus1plus"; SELF
  | SELF; "+"; SELF
  | SELF; "-"; SELF ]
| "mult" RIGHTA
  [ SELF; "*"; SELF
  | SELF; "/"; SELF ]
| "simple" NONA
  [ "("; SELF; ")"
  | INT ((_)) ]
| LEFTA
  [ SELF; "plus1plus"; SELF ] ]
- : unit = ()
\end{ocamlcode}
\captionof{listing}{Extend Grammar at LAST}


\begin{ocamlcode}
EXTEND Gram
  test: LEVEL "mult"
  [[x = SELF ; "plus1plus" ; y = SELF ]];
END ;

p  test;

      - : unit = ()
#   test: [ "add" LEFTA
  [ SELF; "plus1plus"; SELF
  | SELF; "+"; SELF
  | SELF; "-"; SELF ]
| "mult" RIGHTA
  [ SELF; "plus1plus"; SELF
  | SELF; "*"; SELF
  | SELF; "/"; SELF ]
| "simple" NONA
  [ "("; SELF; ")"
  | INT ((_)) ]
| LEFTA
  [ SELF; "plus1plus"; SELF ] ]  
\end{ocamlcode}
\captionof{listing}{Extend Grammar At Level}


\begin{ocamlcode}
EXTEND Gram
  test: BEFORE "mult" [[x = SELF ; "plus1plus" ; y = SELF ]];
END ;

p  test;

    - : unit = ()
#   test: [ "add" LEFTA
  [ SELF; "plus1plus"; SELF
  | SELF; "+"; SELF
  | SELF; "-"; SELF ]
| LEFTA
  [ SELF; "plus1plus"; SELF ]
| "mult" RIGHTA
  [ SELF; "plus1plus"; SELF
  | SELF; "*"; SELF
  | SELF; "/"; SELF ]
| "simple" NONA
  [ "("; SELF; ")"
  | INT ((_)) ]
| LEFTA
  [ SELF; "plus1plus"; SELF ] ]
- : unit = ()  
\end{ocamlcode}
\captionof{listing}{Extend Grammar at BEFORE}

\subsubsection{Example: Expr Parse Tree}

Listing \ref{Expr Parse Tree} is the expr parse tree.

\inputminted[fontsize=\scriptsize]{ocaml}{code/camlp4/expr_parse_tree/first.ml}
\captionof{listing}{Expr Parse Tree\label{Expr Parse Tree}}




When you modify the module \textit{Camlp4.PreCast.Gram}, it will be
\textit{reflected in the toplevel on the fly}. And be careful, it's
probably you never come back and need to restart the toplevel.

When two rules overlapping, the EXTEND statement replaces the
old version by the new one and displays a warning. 


\subsubsection{Debug}
\begin{itemize}

\item We can re-raise the exception so it gets \textit{printed}
  using \textit{Printexc} .

\item \textit{Gram.Entry.print}

\end{itemize}


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "../master"
%%% End: 
